package com.autoreassociate.tool;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.wifi.WifiManager;
import android.os.ConditionVariable;
import android.preference.PreferenceManager;

import com.autoreassociate.AlarmSettingActivity;
import com.autoreassociate.R;
import com.autoreassociate.SettingActivity;
import com.autoreassociate.analysis.MessageLogManager;
import com.autoreassociate.receiver.ConnectionCheckReceiver;
import com.autoreassociate.receiver.WifiStatusReceiver;
import com.autoreassociate.service.CaLifeCycleService;

public class ConnectionAssociateTool extends ContextWrapper 
{
    
    protected static ConnectionAssociateTool connectionAssociateTool;
    
    // 실제 핑을 보내는 IP주소
    protected InetAddress inetAddress;

    // 핑을 보낼 IP주소 
    protected String ipAddress;
    
    // 연결확인용 핑대기 시간
    protected int pingWaitTime;
    
    // WIFI신호를 끊는 RSSI강도 
    protected int disconnectWifiRssiRate;

    // 재접속 연속 실패누적수 
    protected int failCount;

    // 알람 작동중 유무 
    protected boolean isRunningAlarm;
    
    // WIFI연결시 핑체크 알람의 자동 실행유무
    protected boolean isAutoStartAlarm;
    


    // 노티피케이션 표시 사용 유무
    protected boolean notiViewNotiMessage;


    
    protected NotificationManager notificationManager;
    protected WifiManager wifiManager;
    protected ConnectivityManager connectivityManager;
    protected AlarmManager alarmManager;
    protected PendingIntent pingSendServiceAlarmSender;
    protected SharedPreferences sharedPreferences;
    
    protected WifiStatusReceiver wifiStatusReceiver;

    protected MessageLogManager messageLogManager;
    


    private ConditionVariable conditionVariable;

    
    
    
    // Construts------------------------------------------------
    //private ConnectionAssociateTool(Context base, ListView logView) {
    private ConnectionAssociateTool(Context base) {
        super(base);
        
        alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        
        wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
        connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

        conditionVariable = new ConditionVariable();
        
        boolean toastViewToastMessage = sharedPreferences.getBoolean(SettingActivity.TOAST_VIEW_TOAST_MESSAGE, false);
        
        //messageLogManager = new MessageLogManager(base, logView, toastViewToastMessage);
        messageLogManager = new MessageLogManager(base, toastViewToastMessage);

        messageLogManager.printVT("TOOL INIT");
    }
    
    
    
    /**
     * 싱글톤으로 메인툴의 객체생성과 환경설정을 실행한다.
     * 
     * @param base 메인의 context
     * @param logView 로기 기록용 리스트
     * @return 초기화를 마친 싱글톤 객
     */
    //public static ConnectionAssociateTool getInstance(Context base, ListView logView) {
    public static ConnectionAssociateTool getInstance(Context base) {
        //if (connectionAssociateTool == null) {
        // 객체 초기화
        //connectionAssociateTool = new ConnectionAssociateTool(base, logView);
    	connectionAssociateTool = new ConnectionAssociateTool(base);

        // 최초 환경설
        connectionAssociateTool.attributesReset();
            
        //}
        
        // 최초 노티피케이션 아이콘 표
        connectionAssociateTool.showReassociateNotification(R.drawable.state_wait, R.string.noti_start_reassociate_msg);

        return connectionAssociateTool;
    }

    
    
    
    public static ConnectionAssociateTool getInstance() {
        if (connectionAssociateTool == null) {
            //TODO
            //throw new NullPointerException("-------No Context setting---------");
        }
        
        
//        if () {
//        	connectionAssociateTool.showReassociateNotification(R.drawable.state_wait, R.string.noti_start_reassociate_msg, 0);
//        }
        
        return connectionAssociateTool;
    }
    
    
    
    
    public void instanceClose() {
        //conditionVariable.open();
        endAlarm();
        cancelReassociateNotification();
        endWifiStatusReciver();
        // TODO
        connectionAssociateTool = null;
        this.stopService(new Intent(this, CaLifeCycleService.class));
    }
    
    
    
    @Override
    protected void finalize() throws Throwable {
        super.finalize();        
        instanceClose();
    }
 
    
    
    public void attributesReset() {
        
        notiViewNotiMessage = ConnectionAssociateTool.getInstance().getSharedPreferences().getBoolean(SettingActivity.NOTI_VIEW_NOTI_MESSAGE, true);

        // 공유기의 게이트웨이 IP주소를 가져옴. 이 자동 주소설정인 경우 이 주소로 핑을 보내게됨. 공유기에 핑거부가 된경우는 무용지물이 됨. 
        AlarmSettingActivity.DEFAULT_PING_SEND_IP_ADDRESS = intToIp(wifiManager.getDhcpInfo().gateway);
        
        // 공유기 연결중 유무 판단용 핑 대기시간(이 시간을 넘으면 공유기에서 연결을 끊은 경우로 판단.)
        try {
        	pingWaitTime = Integer.parseInt(sharedPreferences.getString(AlarmSettingActivity.PING_WAITING_TIME,
                    AlarmSettingActivity.DEFAULT_PING_WAITING_TIME));
        } catch (Exception e) {
        	pingWaitTime = Integer.parseInt(AlarmSettingActivity.DEFAULT_PING_WAITING_TIME);
        	ConnectionAssociateTool.getInstance().getMessageLogManager().printForceT("DEFAULT_PING_WAITING_TIME : " + AlarmSettingActivity.DEFAULT_PING_WAITING_TIME);
        }

        
        // 알람 자동실행 유무 재설정
        isAutoStartAlarm = sharedPreferences.getBoolean(SettingActivity.BROADCAST_AUTO_START_SERVICE_WHEN_WIFI_ON, false);

        // 접속끊는 RSSI값 재설정.
        disconnectWifiRssiRate = 0;
        String disconnRssiStrengthString =
            sharedPreferences.getString(SettingActivity.BROADCAST_WIFI_DISCONNECT_RSSI_STRENGTH, null);
        
        if (disconnRssiStrengthString != null && disconnRssiStrengthString.length() > 0) {
            disconnectWifiRssiRate = Integer.parseInt(disconnRssiStrengthString);
        }
        
        
        boolean toastViewToastMessage = connectionAssociateTool.getSharedPreferences().getBoolean(SettingActivity.TOAST_VIEW_TOAST_MESSAGE, false);
        messageLogManager.setToastViewToastMessage(toastViewToastMessage);
        
        
        this.resetSendPingIp();
        
        if (isRunningAlarm()) {
            endAlarm();
            startAlarm();
        }
        
        messageLogManager.printVT("Attributes Reset\nSend Ping Ip : %s\nPing Wait Time : %s ms", ipAddress, pingWaitTime);
    }
    
    
    
    public void resetSendPingIp() {
    	
        try {
            if (!sharedPreferences.getBoolean(AlarmSettingActivity.PING_IP_ADDRESS_CUSTOM_SET, false)) {
                // ip 자동선택일 경우
                ipAddress = AlarmSettingActivity.DEFAULT_PING_SEND_IP_ADDRESS;
            } else {
                // ip 수동설정인 경우
                ipAddress = sharedPreferences.getString(AlarmSettingActivity.PING_SEND_IP_ADDRESS,
                        AlarmSettingActivity.DEFAULT_PING_SEND_IP_ADDRESS);
            }

            inetAddress = InetAddress.getByName(ipAddress);
            
            messageLogManager.printVT("Ping reset : %s", ipAddress);
            
        } catch (Exception e) { // UnknownHostException
            inetAddress = null;
            //MainActivity.printVT(R.string.toast_ip_address_init_fail_msg, R.drawable.state_ng);
            //endAlarm();
            //e.printStackTrace();
            return;
        }
    }
    
    
    
    public void sendPing() {

        if (wifiManager == null) {
            attributesReset();
            //Log.e(this.getClass().getName(), "Need invoke attributesReset()");
            //return;
        }
        

        //Vibrator vibrator = (Vibrator)this.getSystemService(Context.VIBRATOR_SERVICE);
        //vibrator.vibrate(200);

        //boolean ping = wifiManager.pingSupplicant();
        //boolean albe = wifiManager.isWifiEnabled();

        int iconDelay = 0;
        
        int status = wifiManager.getWifiState();

        if (status == WifiManager.WIFI_STATE_ENABLED
                && connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected()) {
            //result1 = wifiManager.disconnect();
            //reassociate = wifiManager.reassociate();
            
            try {


                if (ipAddress == null || ipAddress.length() == 0) {
                    AlarmSettingActivity.DEFAULT_PING_SEND_IP_ADDRESS = intToIp(wifiManager.getDhcpInfo().gateway);
                    attributesReset();
                    //MainActivity.printVT(R.string.toast_ip_address_init_fail_msg, R.drawable.state_ng);
                    //return;
                }
                
                if (inetAddress == null) {
                    messageLogManager.printVT(R.string.toast_ip_address_init_fail_msg, R.drawable.state_ng);
                    endAlarm();
                    return;
                }
                
                messageLogManager.printV("Send Ping IP : " + inetAddress.getHostAddress(), R.drawable.state_ping);
                
                //showReassociateNotification(R.drawable.state_ping, R.string.noti_status_send_ping);
                showReassociateNotification(R.drawable.state_ping, null);
                //conditionVariable.block(100);

                if(inetAddress.isReachable(pingWaitTime) == false) {
                    
                    Boolean reassociate = wifiManager.reassociate();
                    
                    //conditionVariable.block(100);
                    /*
                    if (reassociate) {
                        MainActivity.printV(R.string.toast_reassociat_success, R.drawable.state_reassociate);
                    } else {
                        MainActivity.printV(R.string.toast_reassociat_fail, R.drawable.state_reassociate);
                    }
                    */
                    
                    // try reconnection
                    // reassociate결과를 항상 true로 돌리기 때문에 실제 공유기와의 연결을 재확인하기 위해서 다시 핑을 날려서 결과를 확인
                    if(inetAddress.isReachable(pingWaitTime * 2) == true) {
                        // 연결 복구를 확인 한 경우
                        
                        // 전송 실패수 초기화
                        failCount = 0;
                    
                        messageLogManager.printVT(R.string.toast_reassociat_success, R.drawable.state_reassociate);
                        //showReassociateNotification(R.drawable.state_reassociate, R.string.noti_status_rea1000);
                    } else {
                        // 연결 복구에 실패한 경우
                        
                        // 전송 실패수 초기화
                        failCount++;
                        
                        messageLogManager.printV(R.string.toast_reassociat_fail, R.drawable.state_ng);
                        //showReassociateNotification(R.drawable.state_ng, R.string.noti_status_reassociated_ng);
                        showReassociateNotification(R.drawable.state_ng, R.string.noti_status_reassociated_ng);
                        
                        // 부적합 IP에 의한 실패인 경우를 고려해서 IP를 재설정.
                        this.resetSendPingIp();
                    }
                    
                    //conditionVariable.block(1000);
                    
                    
                } else {
                    
                    // 전송 실패수 초기화
                    failCount = 0;
                    
                    //showReassociateNotification(R.drawable.state_conn_ok, R.string.noti_status_conn_ok);
                    showReassociateNotification(R.drawable.state_conn_ok, null);
                    messageLogManager.printV(R.string.toast_no_need_reassociat, R.drawable.state_conn_ok);
                    //conditionVariable.block(1000);
                }


            } catch (IOException e) {
                messageLogManager.printV("IOException");
                e.printStackTrace();
            }
            
            if (isRunningAlarm()) {
                showReassociateNotification(R.drawable.state_wait_alarm, null);
            } else {
                showReassociateNotification(R.drawable.state_wait, null);
            }

        }
    }
    
    
    
    public void sendPingOrReconnect() {
        
        // 화면이 표시된 경우.
        if (wifiManager.isWifiEnabled() && wifiManager.getWifiState() <= WifiManager.WIFI_STATE_DISABLED) {
            // WIFI를 켜두었으나 연결이 안되어 있는 경우 재연결한다.
            connectionAssociateTool.getMessageLogManager().printVT("reconnect()");
            wifiManager.reconnect();
        } else {
            connectionAssociateTool.sendPing();
        }

    }
    
    

    
    
    // Alarm--------------------------------------------------------------
    
    public void startAlarm() {
        
    	if (isRunningAlarm()) {
    		return;
    	}
    	
        pingSendServiceAlarmSender = PendingIntent.getBroadcast(ConnectionAssociateTool.this,
        		0, ConnectionCheckReceiver.REASSOCIATE_INTENT, PendingIntent.FLAG_UPDATE_CURRENT);
                //0, new Intent(ConnectionAssociateTool.this, ConnectionCheckReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);

        // We want the alarm to go off 30 seconds from now.
        //long firstTime = SystemClock.elapsedRealtime();
        long firstTime = System.currentTimeMillis();

        long interval = 0;
        try {
            interval = Long.parseLong(sharedPreferences.getString(AlarmSettingActivity.PING_SEND_INTERVAL,
                    AlarmSettingActivity.DEFAULT_PING_SEND_INTERVAL));
        } catch (Exception e) {
            interval = Long.parseLong(AlarmSettingActivity.DEFAULT_PING_SEND_INTERVAL);
        }

        boolean isRtcWakeUp = sharedPreferences.getBoolean(AlarmSettingActivity.IS_ALARM_RTC_WAKEUP,
                AlarmSettingActivity.DEFAULT_IS_ALARM_RTC_WAKEUP);
        
        // Schedule the alarm!
        alarmManager.setInexactRepeating(isRtcWakeUp ? AlarmManager.RTC_WAKEUP : AlarmManager.RTC,
                        firstTime + interval, interval, pingSendServiceAlarmSender);
        
        setRunningAlarm(true);
        messageLogManager.printVT("Alarm On (interval : " + interval + " ms )", R.drawable.stat_alarm1);
        
        //showAlarmNotification(R.drawable.stat_alarm1, R.string.noti_start_receiver_msg);
        showReassociateNotification(R.drawable.state_wait_alarm, R.string.noti_start_receiver_msg);
        
    }
    
    
    public void endAlarm() {
        
    	if (!isRunningAlarm()) {
    		return;
    	}
    	
        //stopService(new Intent(MainActivity.this, ConnectionReassociateService.class));
        
        setRunningAlarm(false);
        
        //cancelAlarmNotification();
        showReassociateNotification(R.drawable.state_wait, null);
        
        messageLogManager.printVT("Alarm Off", R.drawable.stat_alarm1);
        alarmManager.cancel(pingSendServiceAlarmSender);
    }
    
    
    
    
    
    // Notification----------------------------------------------------------
    /*
    protected void showAlarmNotification(int iconId, int textId) {
        

        // In this sample, we'll use the same text for the ticker and the expanded notification
        //CharSequence text = getText(R.string.noti_start_receiver_msg);
        CharSequence text = getText(textId);

        // Set the icon, scrolling text and timestamp
        Notification notification = new Notification(iconId, text,
                System.currentTimeMillis());
        
        notification.flags = Notification.FLAG_NO_CLEAR;

        // The PendingIntent to launch our activity if the user selects this notification
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);

        // Set the info for the views that show in the notification panel.
        notification.setLatestEventInfo(this, getText(R.string.noti_panal_receiver_running_msg),
                       text, contentIntent);

        
        
        // Send the notification.
        // We use a layout id because it is a unique number.  We use it later to cancel.
        notificationManager.notify(R.string.noti_start_receiver_msg, notification);

    }
    
    protected void cancelAlarmNotification() {
        notificationManager.cancel(R.string.noti_start_receiver_msg);
    }
    */
    
    
    static protected Notification notification = null;
    static protected PendingIntent contentIntent = null;
    
    protected void initReassociateNotification(int iconId, Integer msgId) {
        
        if (notification != null) {
        	return;
        }
        
        // In this sample, we'll use the same text for the ticker and the expanded notification
        CharSequence msgString = null;
        if (msgId != null) {
            msgString = getText(msgId);
        }
    
        // Set the icon, scrolling text and timestamp
        notification = new Notification(iconId, msgString, System.currentTimeMillis());
        
        notification.flags = Notification.FLAG_NO_CLEAR;
                
        contentIntent = PendingIntent.getBroadcast(ConnectionAssociateTool.this, 0,
                ConnectionCheckReceiver.REASSOCIATE_INTENT, PendingIntent.FLAG_UPDATE_CURRENT);
    }
    
    
    
    
    protected void showReassociateNotification(int iconId, Integer msgId) {
    	
        if (!notiViewNotiMessage) {
            return;
        }
    	
    	if (notification == null) {
    		initReassociateNotification(iconId, msgId);
    	}
        
        CharSequence msgString2 = null;
        if (isRunningAlarm()) {
            msgString2 = getText(R.string.noti_panal_receiver_running_msg);
        }
    	
        notification.icon = iconId;
        notification.when = System.currentTimeMillis();
        
        notification.setLatestEventInfo(this, getText(R.string.noti_panal_reassociate_msg),
                msgString2, contentIntent);
        
        notificationManager.notify(R.string.noti_start_reassociate_msg, notification);
    }
    

    protected void cancelReassociateNotification() {
        notificationManager.cancel(R.string.noti_start_reassociate_msg);
        notificationManager = null;
    }

    
    
    
    // BroadcastReceiver
    
    public void restartWifiStatusReceiver() {
        
        // 초기화
        disconnectWifiRssiRate = 0;
        
        String disconnRssiStrengthString =
            sharedPreferences.getString(SettingActivity.BROADCAST_WIFI_DISCONNECT_RSSI_STRENGTH, null);
        
        if (disconnRssiStrengthString != null && disconnRssiStrengthString.length() > 0) {
            disconnectWifiRssiRate = Integer.parseInt(disconnRssiStrengthString);
        }

        
        //TODO 무조건 브로드캐스트 생성되게 되어 있는것 손볼것!!
        
        
        if (wifiStatusReceiver != null) {
            // 초기화
            unregisterReceiver(wifiStatusReceiver);
        } else {
            wifiStatusReceiver = new WifiStatusReceiver(); 
        }


        
        //if (isAutoStartAlarm || disconnectWifiRssiRate != 0) {
        IntentFilter filter = null;
        //if (isAutoStartAlarm) {
        filter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
        registerReceiver(wifiStatusReceiver, filter);
        //}

        filter = new IntentFilter(WifiStatusReceiver.RECHECK_WIFI_DISCONNECTION);
        registerReceiver(wifiStatusReceiver, filter);
        
        filter = new IntentFilter(WifiStatusReceiver.RECHECK_WIFI_CONNECTION);
        registerReceiver(wifiStatusReceiver, filter);
        
        
        registerReceiver(wifiStatusReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));

        // 화면 켤때 연결 복구할경우를 위한 브로드 캐스트 리시버 등록
        filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
        registerReceiver(wifiStatusReceiver, filter);
        
        
        if (disconnectWifiRssiRate != 0) {
            filter = new IntentFilter(WifiManager.RSSI_CHANGED_ACTION);
            registerReceiver(wifiStatusReceiver, filter);
        }

        //}
    }
    
    
    public void endWifiStatusReciver() {
        if (wifiStatusReceiver != null) {

            unregisterReceiver(wifiStatusReceiver);
            wifiStatusReceiver = null;
        }
        
    }
    
    
    /**
     * 일회성 브로드캐스트 전송을 실행
     * 
     * @param intent
     * @param waitingTime
     */
    public void shotPendingIntent(Intent intent, long waitingTime) {
    	
        PendingIntent sender = PendingIntent.getBroadcast(
        		this.getApplicationContext(),
                1,
                intent,
                PendingIntent.FLAG_ONE_SHOT);

        // Schedule the alarm!
        AlarmManager alarmManager = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + waitingTime, sender);
    }
    
    
    
    
    
    // SharedPreferences
    public String pingIpResetFromDHCP() {

        
        wifiManager = (WifiManager)this.getSystemService(Context.WIFI_SERVICE);

        if (!sharedPreferences.getBoolean(AlarmSettingActivity.PING_IP_ADDRESS_CUSTOM_SET, false)) {
            AlarmSettingActivity.DEFAULT_PING_SEND_IP_ADDRESS = intToIp(wifiManager.getDhcpInfo().gateway);
            
            Editor editor = sharedPreferences.edit();           
            //editor.putString(AlarmSettingActivity.PING_SEND_IP_ADDRESS, ipAddress);
            editor.putString(AlarmSettingActivity.PING_SEND_IP_ADDRESS, AlarmSettingActivity.DEFAULT_PING_SEND_IP_ADDRESS);
            //editor.putString(AlarmSettingActivity.PING_SEND_IP_ADDRESS, null);
            editor.commit();
        }
        
        ipAddress = sharedPreferences.getString(AlarmSettingActivity.PING_SEND_IP_ADDRESS,
                AlarmSettingActivity.DEFAULT_PING_SEND_IP_ADDRESS);
        
        try {
            inetAddress = InetAddress.getByName(ipAddress);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

        messageLogManager.printVT("send ping Address Reseted:\n" + sharedPreferences.getString(AlarmSettingActivity.PING_SEND_IP_ADDRESS, null));
        
        return ipAddress;
    }
    
    
    
    
    // INFO
    public String getDhcpInfo() {
        
        DhcpInfo dhcpInfo = wifiManager.getDhcpInfo();
        String gatewayString = intToIp(dhcpInfo.gateway);
        String dns1String = intToIp(dhcpInfo.dns1);
        String dns2String = intToIp(dhcpInfo.dns2);
        
        boolean isPingAcceptAbleGateway = false;
        boolean isPingAcceptAbleDns1 = false;
        boolean isPingAcceptAbleDns2 = false;
        boolean isPingAcceptAbleSendPingIp = false;
        
        String gatewaySendPingResult = "";
        
        try {
            isPingAcceptAbleGateway = InetAddress.getByName(gatewayString).isReachable(pingWaitTime);
            isPingAcceptAbleDns1 = InetAddress.getByName(dns1String).isReachable(pingWaitTime);
            isPingAcceptAbleDns2 = InetAddress.getByName(dns2String).isReachable(pingWaitTime);
            isPingAcceptAbleSendPingIp = inetAddress.isReachable(pingWaitTime);
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if (!isPingAcceptAbleGateway || !isPingAcceptAbleSendPingIp) {
            gatewaySendPingResult = "\n\n" + getText(R.string.gateway_not_allow_ping);
        }
        
        
        
        return String.format((String)getText(R.string.dhcp_info_format),
                             intToIp(dhcpInfo.ipAddress),
                             intToIp(dhcpInfo.gateway),
                             intToIp(dhcpInfo.netmask),
                             intToIp(dhcpInfo.dns1),
                             intToIp(dhcpInfo.dns2),
                             intToIp(dhcpInfo.serverAddress),
                             dhcpInfo.leaseDuration,
                             inetAddress,
                             isPingAcceptAbleGateway,
                             isPingAcceptAbleDns1,
                             isPingAcceptAbleDns2,
                             isPingAcceptAbleSendPingIp,
                             gatewaySendPingResult);
    }
    
    
    
    
    // UTIL
    public String intToIp(int i) {
        return ( i        & 0xFF) + "." +
                ((i >>  8 ) & 0xFF) + "." +
                ((i >> 16 ) & 0xFF) + "." +
                ((i >> 24 ) & 0xFF);
    }
    
    
    
    
    
    
    // set,get--------------------------------------------------
    public void setRunningAlarm(boolean isRunningAlarm) {
        this.isRunningAlarm = isRunningAlarm;
    }

    public boolean isRunningAlarm() {
        return isRunningAlarm;
    }
    
    
    public SharedPreferences getSharedPreferences() {
        return sharedPreferences;
    }

    public void setSharedPreferences(SharedPreferences sharedPreferences) {
        this.sharedPreferences = sharedPreferences;
    }
    
    
    public MessageLogManager getMessageLogManager() {
        return messageLogManager;
    }

    public void setMessageLogManager(MessageLogManager messageLogManager) {
        this.messageLogManager = messageLogManager;
    }
    
    
    public WifiManager getWifiManager() {
        return wifiManager;
    }
    
    public int getDisconnectWifiRssiRate() {
        return disconnectWifiRssiRate;
    }
    
    public boolean isAutoStartAlarm() {
        return isAutoStartAlarm;
    }
}
